﻿/*globals net,FG,Utilities*/
Array.prototype.contains = function (obj) {
    var i = this.length;
    while (i--) {
        if (this[i] === obj) {
            return true;
        }
    }
    return false;
};

var Library = {};

Library.ValidateNumber = function (chunk, ignoreBlanks, message, override) {
    if (chunk.error === "") {
        var value = chunk.getValue();
        if (value.toUpperCase() === override) return true;
        if (ignoreBlanks) value = value.replace(/ /g, "");

        if (!((value - 0) == value && value.length > 0)) {
            chunk.setError((!message ? "please enter a numeric value" : message));
        }
        else {
            return true;
        }
    }
    return false;
};

Library.ValidateNumberLessThan = function (chunk, limit, message, allowEqual) {
    if (chunk.error === "") {
        if (!((chunk.getValue() - 0) == chunk.getValue()
                && chunk.getValue().length > 0
                && (chunk.getValue() < limit || (chunk.getValue() <= limit && allowEqual)))) {
            chunk.setError((!message ? "please enter a numeric value under " + limit : message));
        }
        else {
            return true;
        }
    }
    return false;
};

Library.ValidateNumberGreaterThan = function (chunk, limit, message) {
    if (chunk.error === "") {
        if (!((chunk.getValue() - 0) == chunk.getValue() && chunk.getValue().length > 0 && chunk.getValue() > limit)) {
            chunk.setError((!message ? "please enter a numeric value over " + limit : message));
        }
        else {
            return true;
        }
    }
    return false;
};

Library.ValidateRegex = function (chunk, regex, message, overrideValues) {
    if (overrideValues) {
        for (var i = 0; i < overrideValues.length; i++) {
            if (overrideValues[i] === chunk.getValue()) return true;
        }
    }
    if (chunk.error === "") {
        if (!regex.test(chunk.getValue())) {
            chunk.setError(message);
        }
        else {
            return true;
        }
    }
    return false;
};

Library.ValidateEmail = function (chunk, message, overrideValues) {
    var chunkValue = chunk.getValue();
    if (chunkValue.includes("<")) {
        chunk.setError("Please remove < from email address");
        return false;
    }

    if (chunkValue.includes(">")) {
        chunk.setError("Please remove > from email address");
        return false;
    }

    var regex = /^[^@.]{1}[^\@]*\@[^@]+\.[^@]*[^@.]{1}/;

    return Library.ValidateRegex(chunk, regex, message, overrideValues);
};

//Validates a text after stripping out all spaces
//Example: To handle scenario of validating a valid NI number even if user enters spaces between the alphanumeric digits
Library.ValidateRegexWithSpaces = function (chunk, regex, message) {

    var chunkValue = (chunk.getValue()).replace(/ /g, "");
    if (chunk.error === "") {
        if (!regex.test(chunkValue)) {
            chunk.setError(message);
        }
        else {
            return true;
        }
    }
    return false;
};

Library.ValidatePassword = function (chunk) {
    if (chunk.error === "") {
        if (chunk.control[0].value !== chunk.control[1].value) {
            chunk.setError("Your passwords don't match. Please try again.");
        }
        else {
            //chunk.setError("")
            return true;
        }
    }
    return false;
};


Library.ValidateMatches = function (chunk, matchingChunk, error) {
    if (chunk.error === "") {
        if (chunk.getValue() !== matchingChunk.getValue()) {
            chunk.setError(error);
        }
        else {
            //chunk.setError("")
            return true;
        }
    }
    return false;
};

Library.ValidateUsername = function (chunk) {

    var saveButton = document.getElementById("saveButton");

    var url = "ajax/usernamecheck.aspx?username=" + chunk.getValue();
    new net.ContentLoader(url, function () {
        if (this.req.responseText == "True") {
            errorMessage = (chunk.configuration.errorMessage ? chunk.configuration.errorMessage : "this username already exists");
            chunk.setError(errorMessage);
            chunk.usernameExistsError = "exists";
            if (saveButton) saveButton.style.display = "none";
        }
        else {
            chunk.usernameExistsError = "";
            chunk.setError("");
            chunk.displayOk(true);
            FG.username = chunk.getValue();
            if (saveButton) saveButton.style.display = "inline";
        }
    });
};

Library.ValidateDateGreaterThan = function (chunk, value, noDays) {
    if (chunk.error === "") {
        var enteredDate = new Date(chunk.getValue());
        var compareDate;

        if (value === "") {  //GH 5 Aug 2011 - If no date use todays date
            compareDate = new Date();
        }
        else {
            compareDate = new Date(value);
        }

        var adjustedCompareDate = compareDate;
        
        if (noDays) {   //noDays is set to true if chunk only has months and years, then set the date being compared to the 1st day of month, so will pass if same month as chunk
            adjustedCompareDate = new Date(compareDate.getFullYear(), compareDate.getMonth(), "01");
        }

        if (enteredDate < adjustedCompareDate) {
            chunk.setError("please enter a date after " + Library.FormatDate(compareDate));
        }
        else {
            return true;
        }
    }
    return false;
};

Library.ValidateDateGreaterThanChunk = function (chunk, chunkId, noDays) {
    var target = FG.getChunk(chunkId);
    if (!target) return false;
    return Library.ValidateDateGreaterThan(chunk, target.getValue(), noDays);
};

Library.ValidateDateLessThan = function (chunk, value) {
    if (chunk.error === "") {
        var enteredDate = new Date(chunk.getValue());
        var compareDate;

        if (value === "") {  //GH 5 Aug 2011 - If no date use todays date
            compareDate = new Date();
        }
        else {
            compareDate = new Date(value);
        }
        
        if (enteredDate > compareDate) {
            chunk.setError("please enter a date before " + Library.FormatDate(compareDate));
        }
        else {
            return true;
        }
    }
    return false;
};

Library.ValidateDateLessThanChunk = function (chunk, chunkId) {
    var target = FG.getChunk(chunkId);
    if (!target) return false;
    return Library.ValidateDateLessThan(chunk, target.getValue());
};

Library.ValidateDateNotInFuture = function (chunk) {
    var today = new Date().toDateString();
    return (Library.ValidateDateLessThan(chunk, today));
};

Library.ValidateDateInFuture = function (chunk) {
    var today = new Date().toDateString();
    return (Library.ValidateDateGreaterThan(chunk, today));
};

Library.ValidateDate = function (chunk) {
    if (chunk.error === "") {
        //var enteredDate = new Date(chunk.getValue());
        var enteredDate = Library.GetValidatedDate(chunk.getValue());
        if (enteredDate == "NaN" || enteredDate == "Invalid Date") {
            chunk.setError("please enter a valid date");
            return false;
        }
        else {
            chunk.setValue(Library.FormatDate(enteredDate));
            return true;
        }
    }
};

Library.FormatDate = function (dt) {
    return dt.getDate().toString() + " " +
            ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"][dt.getMonth()] +
            " " + dt.getFullYear().toString();
};

Library.GetValidatedDate = function (strDate) {
    //	replace dots with /
    strDate = strDate.replace(/\./g, "/");
    //	replace \ with /
    strDate = strDate.replace(/\\/g, "/");
    //	replace - with space (if dd-mmm-yyy) else with /
    var ptn = /[a-zA-Z]/;
    if (ptn.test(strDate)) {
        strDate = strDate.replace(/-/g, " ");
    }
    else {
        strDate = strDate.replace(/-/g, "/");
    }

    var newStrDate = null;

    //if there is only 1 / remove it so that the next bit of code will add the / back in
    if (strDate.indexOf("/") != -1) {
        var strDateParts = strDate.split("/");
        if (strDateParts.length != 3) {
            newStrDate = strDate.replace("/", "");
            strDate = newStrDate;
        }
    }

    // if there are no / add them in
    if ((strDate.indexOf("/") == -1) && (strDate.indexOf(" ") == -1)) {
        try {
            newStrDate = strDate.substr(0, 2) + "/" + strDate.substr(2, 2) + "/" + strDate.substr(4, 4);
            strDate = newStrDate;
        }
        catch (e1) {
            //sting not in the format 01011976 so carry on
        }
    }

    //if there are / with leading or trailing spaces then replace
    while ((strDate.indexOf(" /") != -1) || (strDate.indexOf("/ ") != -1)) {
        try {
            newStrDate = strDate.replace(" /", "/").replace("/ ", "/");
            strDate = newStrDate;
        }
        catch (e2) {
        }
    }


    //	switch days and months
    ptn = /^\d{1,2}\D\d{1,2}\D/;
    if (ptn.test(strDate)) {
        var strMonth;
        ptn = /^\d\D/;
        if (ptn.test(strDate)) {
            strMonth = strDate.substr(0, 1);
            ptn = /^\d\D\d\D/;
            if (ptn.test(strDate)) {
                strDate = strDate.substr(2, 2) + strMonth + strDate.substr(3);
            }
            else {
                strDate = strDate.substr(2, 3) + strMonth + strDate.substr(4);
            }
        }
        else {
            strMonth = strDate.substr(0, 2);
            ptn = /^\d\d\D\d\D/;
            if (ptn.test(strDate)) {
                strDate = strDate.substr(3, 2) + strMonth + strDate.substr(4);
            }
            else {
                strDate = strDate.substr(3, 3) + strMonth + strDate.substr(5);
            }
        }
    }

    //get the year part if the format is dd/mm/yy
    ptn = new RegExp("/");
    if (ptn.test(strDate)) {
        var aDate = strDate.split("/");
        var strYear = aDate[2];
        //if the year is only 2 digits change it to 4
        if (strYear.length < 4) {
            var intYear = parseInt(strYear, 10);
            //if the 2 digits are > than 29 add 1900 else add 2000
            if (intYear > 29) {
                intYear = intYear + 1900;
            } else {
                intYear = intYear + 2000;
            }
            strYear = intYear.toString();
            strDate = aDate[0] + "/" + aDate[1] + "/" + strYear;
        }
    }

    var dt = new Date(strDate);
    return dt;
};

Library.ValidateLength = function (chunk, length, message) {
    if (chunk.error === "") {
        var enteredText = chunk.getValue(true);
        if (enteredText.length < length) {
            chunk.setError((!message ? ("please enter at least " + length + " characters") : message));
            return false;
        }
        else {
            return true;
        }
    }
};

Library.ValidateLengthMax = function (chunk, length, message) {
    if (chunk.error === "") {
        var enteredText = chunk.getValue(true);
        if (enteredText.length > length) {
            chunk.setError((!message ? ("please enter no more than " + length + " characters") : message));
            return false;
        }
        else {
            return true;
        }
    }
};

Library.ValidateExactLength = function (chunk, length, message, override) {
    if (chunk.error === "") {
        var enteredText = chunk.getValue(true);
        if (enteredText.toUpperCase() === override) return true;
        if ((enteredText.length < length) || (enteredText.length > length)) {
            chunk.setError((!message ? ("please enter " + length + " characters") : message));
            return false;
        }
        else {
            return true;
        }
    }
};

Library.CompareChunkToChunk = function (chunk, compareToChunkId, operator, message) {
    if (chunk.error === "") {
        var chunkValue = chunk.getValue();
        var compareToChunk = FG.getChunk(compareToChunkId);
        var compareToChunkValue = compareToChunk.getValue();
        var result = false;
        switch (operator) {
            case "=":
                if (chunkValue == compareToChunkValue) {
                    result = true;
                } else {
                    chunk.setError((!message ? (chunk.label + " must be the same as " + compareToChunk.label) : message));
                    result = false;
                }
                break;
            case ">":
                if (chunkValue > compareToChunkValue) {
                    result = true;
                } else {
                    chunk.setError((!message ? (chunk.label + " must be greater than " + compareToChunk.label) : message));
                    result = false;
                }
                break;
            case "<":
                if (chunkValue < compareToChunkValue) {
                    result = true;
                } else {
                    chunk.setError((!message ? (chunk.label + " must be smaller than " + compareToChunk.label) : message));
                    result = false;
                }
                break;
            case "<=":
                if (chunkValue <= compareToChunkValue) {
                    result = true;
                } else {
                    chunk.setError((!message ? (chunk.label + " must be smaller than or equal to " + compareToChunk.label) : message));
                    result = false;
                }
                break;
            case "!=":
                if (chunkValue != compareToChunkValue) {
                    result = true;
                } else {
                    chunk.setError((!message ? (chunk.label + " must not be the same as " + compareToChunk.label) : message));
                    result = false;
                }
                break;
            case "C": //CONTAINS >> to ensure that if chunkValue is not empty, then compareToChunkValue cannot be empty
                if ((chunkValue !== "") && (((compareToChunk.type !== "Checkbox") && (compareToChunkValue !== "")) ||
                                             ((compareToChunk.type === "Checkbox") && (compareToChunkValue !== false)))) { //if compareToChunk is a checkbox, then compareToChunkValue must not be false
                    result = true;
                } else {
                    chunk.setError((!message ? (compareToChunk.label + " must contain information relevant to " + chunk.label) : message));
                    result = false;
                }
                break;
        }
        return result;
    }
};

Library.CompareChunkToChunks = function (chunk, compareToChunkIds, operator, message) {
    var result = false;
    var compareToChunkIdArray = null;
    var compareToChunkIdIndex = 0;
    var compareToChunkId = null;
    compareToChunkIds = compareToChunkIds.replace("[", "");
    compareToChunkIds = compareToChunkIds.replace("]", "");

    compareToChunkIdArray = (!isNaN(compareToChunkIds - 0)) ? [compareToChunkIds] : compareToChunkIds.split(",");
    for (compareToChunkIdIndex = 0; compareToChunkIdIndex < compareToChunkIdArray.length; compareToChunkIdIndex++) {
        if (compareToChunkIdArray[compareToChunkIdIndex] != null && compareToChunkIdArray[compareToChunkIdIndex] !== "") {
            compareToChunkId = compareToChunkIdArray[compareToChunkIdIndex];
            result = Library.CompareChunkToChunk(chunk, compareToChunkId, operator, message);
            if (!result) break; //break on first mismatch itself
        }
    }

    return result;
};

/*
Example:
Library.CompareChunkToChunkForSpecificAnswer(this, 569, "!=", "Y", "You cannot be a tenant of both Howard Cottage Housing Association and North Herfordshire Homes");
So the function will return a false ONLY if chunk & compareToChunkId have the same specificChunkAnswer of "Y". 
If either or both of the chunks have an answer that is not equal to "Y", then this function will return a true
*/
Library.CompareChunkToChunkForSpecificAnswer = function (chunk, compareToChunkId, operator, specificChunkAnswer, message) {
    var result = false;
    var chunkValue = chunk.getValue();
    var compareToChunk = FG.getChunk(compareToChunkId);
    var compareToChunkValue = compareToChunk.getValue();
    //Do the comparison only if both Chunks have the same answer as specificChunkAnswer
    if ((chunkValue === specificChunkAnswer) && (compareToChunkValue === specificChunkAnswer)) {
        result = Library.CompareChunkToChunk(chunk, compareToChunkId, operator, message);
    }
    else {
        result = true;
    }
    return result;
};

//KN 22 Jul 2011 check that 1 chunk in the section has been answered
Library.validateSectionOneChunkMandatory = function (section, mandatoryText) {
    var answered = false;
    section.validationText = mandatoryText;
    //loop through chunks in the section and chick if answered
    var currentAnswerIndex = FG.getCurrentAnswerIndex();
    for (var i = 0; i < section.chunks.length; i++) {
        if ((!section.chunks[i].hidden[currentAnswerIndex]) && (section.chunks[i].isAnswered())) {
            answered = true;
            break;
        }
    }
    return (answered);
};

//KN 30 Nov 2012 loops through the chunks and returns true if one of the chunks has been answered 
Library.validateOneChunkMandatory = function (chunks) {
    var answered = false;

    //loop through chunks in array and see if one is answered
    for (var i = 0; i < chunks.length; i++) {
        if (FG.getChunk(chunks[i]).isAnswered()) {
            answered = true;
            break;
        }
    }
    return (answered);
};

//GH 02 Aug 2012 check that 1 chunk in the array of chunks has been answered in a section
Library.validateChunksOneChunkMandatory = function (section, chunks, mandatoryText) {
    section.validationText = mandatoryText;

    return (Library.validateOneChunkMandatory(chunks));
};

//This validates on how many of the check box groups have at least 1 checkbox ticked
Library.validateCheckboxGroupChunksTotalSelected = function (chunks, limit) {
    var chunkAnswers;
    var x;
    var counter = 0;
    for (x = 0; x < chunks.length; x++) {
        chunkAnswers = FG.getChunk(chunks[x]).getValue();
        if (chunkAnswers.substring(0, 1) == ";") chunkAnswers = chunkAnswers.substring(1);
        if (chunkAnswers.substring((chunkAnswers.length - 1), chunkAnswers.length) == ";") chunkAnswers = chunkAnswers.substring(0, (chunkAnswers.length - 1));
        if (chunkAnswers === "") continue;
        if (chunkAnswers.split(";").length > 0) counter++;
    }
    if (counter > limit) return false;

    return true;
};

//The above function only tells you how many of the check box groups have at least 1 checkbox ticked
//The function below validates the total number of checkboxes that are ticked across all checkbox groups
//and allows an upper and lower limit in case you want to make sure at least one checbox has been ticked (mandatory)
Library.validateCheckboxGroupChunksTotalCheckboxesTicked = function (chunks, upperLimit, lowerLimit) {
    var chunkAnswers;
    var x;
    var counter = 0;
    if (lowerLimit == undefined) { lowerLimit = 0; }

    for (x = 0; x < chunks.length; x++) {
        chunkAnswers = FG.getChunk(chunks[x]).getValue();
        if (chunkAnswers.substring(0, 1) == ";") chunkAnswers = chunkAnswers.substring(1);
        if (chunkAnswers.substring((chunkAnswers.length - 1), chunkAnswers.length) == ";") chunkAnswers = chunkAnswers.substring(0, (chunkAnswers.length - 1));
        if (chunkAnswers === "") continue;
        if (chunkAnswers.split(";").length > 0) counter = counter + chunkAnswers.split(";").length;
    }
    if (counter > upperLimit) return false;
    if (counter < lowerLimit) return false;

    return true;
};

Library.validateCheckboxGroupOptionsSelected = function (callingChunk, chunks, limit) {

    var chunkAnswers = callingChunk.getValue();
    if (chunkAnswers.substring(0, 1) == ";") chunkAnswers = chunkAnswers.substring(1);
    if (chunkAnswers.substring((chunkAnswers.length - 1), chunkAnswers.length) == ";") chunkAnswers = chunkAnswers.substring(0, (chunkAnswers.length - 1));

    if (chunkAnswers.split(";").length > 1) {
        callingChunk.setError("you may only select 1 checkbox for this question");
        return false;
    }

    for (var x = 0; x < chunks.length; x++) FG.getChunk(chunks[x]).setError("");

    return true;
};

Library.toTitleCaseFirstWord = function (chunk) {
    if  (chunk.getValue()) {
        var str = chunk.getValue().charAt(0).toUpperCase() + chunk.getValue().slice(1);
        chunk.setValue(str);
    }
};

Library.toTitleCase = function (chunk) {
    if (chunk.getValue()) {
        var str = chunk.getValue().replace(/\b[\w']+\b/g, function (txt) { return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); });
        chunk.setValue(str);
    }
};

Library.toUpperCase = function (chunk) { chunk.setValue(chunk.getValue().toUpperCase()); };

Library.dateRangeCondition = function (chunkId, value, datePart, targetAfter, allowEqual) {

    var chunk = FG.getChunk(chunkId);
    if (chunk == null) return false;

    var chunkDate = new Date(chunk.getValue());
    if (isNaN(chunkDate)) return false;

    var targetDate = new Date();

    switch (datePart) {
        case "day":
            targetDate.setDate(targetDate.getDay() + value);
            break;
        case "month":
            targetDate.setMonth(targetDate.getMonth() + value);
            break;
        case "year":
            targetDate.setFullYear(targetDate.getFullYear() + value);
            break;
    }

    if (targetAfter) {
        if (allowEqual) {
            return (chunkDate >= targetDate);
        }
        else {
            return (chunkDate > targetDate);
        }
    }
    else {
        if (allowEqual) {
            return (chunkDate <= targetDate);
        }
        else {
            return (chunkDate < targetDate);
        }
    }

};

Library.ageGreaterThan = function (chunk, age, message) {
    var enteredAge = Utilities.age(new Date(chunk.getValue()));

    if (enteredAge < age || !enteredAge) {
        chunk.setError((!message ? ("age must be greater than  " + age) : message));
        return false;
    }
    return true;
};

Library.ageLessThan = function (chunk, age, message) {
    var enteredAge = Utilities.age(new Date(chunk.getValue()));

    if (enteredAge > age || !enteredAge) {
        chunk.setError((!message ? ("age must be less than " + age) : message));
        return false;
    }
    return true;
};

// datepart: 'y', 'm', 'w', 'd', 'h', 'n', 's'
Library.dateDiff = function (datepart, fromdate, todate) {
    datepart = datepart.toLowerCase();
    var diff = todate - fromdate;
    var divideBy = {
        y: 31557600000,
        m: 2628000000,
        w: 604800000,
        d: 86400000,
        h: 3600000,
        n: 60000,
        s: 1000
    };

    return Math.floor(diff / divideBy[datepart]);
};

Library.setMandatoryIfAnotherChunkAnswered = function (chunk, answeredChunk) {

    //use in validation to make a question mandatory if another is answered (FG.setMandatoryIfAnotherChunkAnswered)
    var value = chunk.getValue();

    if (answeredChunk.getValue() === "" || (value !== "" && value !== null)) {
        chunk.setError("");
        return true;
    }
    else {
        chunk.setError(chunk.mandatoryText);
        return false;
    }
};

//06072012 - Aby - Compare Chunk Value To Expected Value
Library.CompareChunkValueToExpectedValue = function (chunk, expectedValue, operator) {

    if (chunk === undefined || chunk === null || operator === undefined || operator === null || expectedValue === undefined || expectedValue === null) return;

    var chunkValue = chunk.getValue();
    var result = false;

    switch (operator) {
        case "=":
            if (chunkValue === expectedValue) {
                result = true;
            }
            break;
        case ">":
            if (chunkValue > expectedValue) {
                result = true;
            }
            break;
        case "<":
            if (chunkValue < expectedValue) {
                result = true;
            }
            break;
        case "<=":
            if (chunkValue <= expectedValue) {
                result = true;
            }
            break;
        case ">=":
            if (chunkValue >= expectedValue) {
                result = true;
            }
            break;
        case "!=":
            if (chunkValue !== expectedValue) {
                result = true;
            }
            break;
        case "C": //CONTAINS >> to ensure that if chunkValue is not empty, then expectedValue cannot be empty
            if ((chunkValue !== "") && (expectedValue !== "")) {
                result = true;
            }
            break;
    }
    return result;
};

Library.formatCurrency = function (chunk, blankValue) {
    if (chunk.getValue().toLowerCase() !== blankValue.toLowerCase() && chunk.getValue() !== "") {
        Library.ValidateNumber(chunk, true, "Please put the amount in the correct format. Use numbers not letters or words." +
            "Separate pounds from pence with a full-stop. Don't use commas or any other punctuation.");
        if (chunk.error === "") chunk.setValue(parseFloat(Math.round(chunk.getValue() * 100) / 100).toFixed(2));
    }
};

Library.ValidateMandatoryIfChunksAnswered = function (chunks, mandatoryChunk, message) {

    for (var i = 0; i < chunks.length; i++) {
        var chunk = FG.getChunk(chunks[i]);
        var value = chunk.getValue();
        value = value.replace(/ /g, "");

        if (value.length > 0
            && (FG.getChunk(mandatoryChunk).getValue() === false || FG.getChunk(mandatoryChunk).getValue() === "" || FG.getChunk(mandatoryChunk).getValue() === "£0.00")) {
            FG.getChunk(mandatoryChunk).setError((!message ? "this field is mandatory" : message));
            return false;
        }
        else {
            FG.getChunk(mandatoryChunk).setError("");
        }
    }
    return true;
};

Library.ageLessThanInMonths = function (months, chunk) {
    var currentDate = new Date();
    var birthDate = new Date(chunk.getValue());

    var ageInMonths = Library.dateDiff('m', currentDate, birthDate);

    if (ageInMonths > months) {
        chunk.setError("This date must be within the next " + months + " months.");
        return false;
    }
    else {
        chunk.setError("");
        return true;
    }
};

//allow only one radio button in array to be selected at a time
Library.onlyOneRadioQuestionSelected = function (chunkClicked, chunks) {
    var i;
    var chunk;
    for (i = 0; i < chunks.length; i++) {
        chunk = FG.getChunk(chunks[i]);
        if (chunkClicked.id == chunk.id || chunkClicked.getValue() === "") continue;
        chunk.setValue("");
        chunk.setError("");
        chunk.displayOk(false);
    }
};

Library.ValidateOnlyLetters = function (chunk) {
    var letters = /^[a-zA-Z\s]*$/
    var value = chunk.getValue();
    if (value.match(letters)) {
        return true;
    }
    else {
        chunk.setError("Only letters are allowed in this field.");
        return false;
    }
};

Library.CheckboxesLessThanTicked = function (chunk, numberTicked) {
    var value = chunk.getValueArray();   /*this is an array of checkboxes that are ticked*/
    if (value.length <= numberTicked) {
        return true;
    }
    else {
        chunk.setError("Please select " + numberTicked + " or less");
        return false;
    }
};

Library.ValidateValueExists = function (chunk, message, elementCode, statuses, entityTypeId, overrideValue, partnerId) {

    var value = chunk.getValue();
    if (value.toUpperCase() === overrideValue.toUpperCase()) return true;
    if (value === "") return true;

    var url = "ajax/other.aspx?action=valueexists&v=" + value + "&e=" + elementCode + "&s=" + statuses + "&et=" + entityTypeId;

    // If this is a CoC, ignore values that exist and are linked to the current customer.
    if (FG.externalCustomerId > 0) url += "&ei=" + FG.externalCustomerId;

    if (partnerId) url += "&p=" + partnerId;        // If a partner ID is added, check only for duplicates for entities linked to that partner.

    var ajax = new net.ContentLoader(url, null, null, null, null, null, false);
    var response = eval(ajax.req.responseText);
    if (response[0]) {
        chunk.setError(message);
        return false;
    } else {
        chunk.setError("");
        return true;
    }
};

Library.validateMoneyMandatory = function (chunk, message, ignoreBlanks) {
    if (chunk.error === "") {
        var value = chunk.getValue();
        if (ignoreBlanks) value = value.replace(/ /g, "");

        if (value == "£0.00" || value == "" || value == "£" || value == "£0") {
            chunk.setError((!message ? "please enter a value" : message));
        }
        else {
            return true;
        }
    }
    return false;
};
//pass in a chunk to check, a collection of values to check with corresponding chunks and messages
//used in the scenario where say you have preferred method of contact (email/text/phone), and want to
//force the user if email is selected to enter an email address 
// e.g Library.ValidateChunkInvalidSelection(this, ["1", "2", "3"], [100, [101, 102], 103], ["please enter email", "please enter a phone no.", "please enter a mobile no."])
Library.ValidateChunkInvalidSelection = function (chunk, valuesToCheck, chunksToCheck, messages) {
    var value = chunk.getValue();

    for (var i = 0; i < valuesToCheck.length; i++) {
        if (!chunksToCheck[i].length) {
            if (valuesToCheck[i] == value) {
                if (FG.getChunk(chunksToCheck[i]).getValue() == "") {
                    chunk.setError(messages[i]);
                    return false;
                }
                else {
                    chunk.setError("");
                    return true;
                }
            }
        }
        else {
            var testValue = true;
            for (var j = 0; j < chunksToCheck[i].length; j++) {
                if (valuesToCheck[i] == value) {
                    testValue = false;
                    if (FG.getChunk(chunksToCheck[i][j]).getValue() !== "") {
                        testValue = true;
                        break;
                    }
                }
            }
            if (!testValue) {
                chunk.setError(messages[i]);
            }
            else {
                chunk.setError("");
            }
            return testValue;
        }
    }

};

Library.totalSection = function (totalChunkId, sectionId, firstCharacterCheck) {
    var totalChunk = FG.getChunk(totalChunkId);
    var chunk;
    var total = 0;

    if (totalChunk) {
        var section = FG.getSection(sectionId);

        if (section) {
            var chunkValue = 0;

            for (i = 0; i < section.chunks.length; i++) {
                chunk = section.chunks[i];
                
                if (chunk) {
                    //the total chunk could be in the same section as the chunks to sum, if so, ignore it
                    if (chunk.id !== totalChunkId) {
                        switch (chunk.type) {
                            case "Textbox":
                                //firstCharacterCheck is used to check if value needs to start with say a £ sign
                                if (!firstCharacterCheck || chunk.getValue().indexOf(firstCharacterCheck) === 1) ;
                                {
                                    //Store the chunk value and so that next dropdown can do calculation using value
                                    chunkValue = +chunk.getValue().replace("£", "").replace(",", "");

                                    if (!isNaN(chunkValue)) {

                                        total += chunkValue;
                                    }
                                }
                                
                                break;
                        }
                    }
                }
            }
        }

        totalChunk.setAnswer(Utilities.formatMoney(total, true), 0);
    }
};

Library.totalChunks = function (totalChunkId, chunks) {
    var totalChunk = FG.getChunk(totalChunkId);
    var chunk;
    var total = 0;

    if (totalChunk) {
        for (i = 0; i < chunks.length; i++) {
            chunk = FG.getChunk(chunks[i]);
            var chunkValue = 0;

            if (chunk) {
                //the total chunk could be in the same section as the chunks to sum, if so, ignore it
                if (chunk.id !== totalChunkId) {
                    //Store the chunk value and so that next dropdown can do calculation using value
                    chunkValue = +chunk.getValue().replace("£", "").replace(",", "");

                    if (!isNaN(chunkValue)) {

                        total += chunkValue;
                    }

                }
            }
        }

        totalChunk.setAnswer(Utilities.formatMoney(total, true), 0);
    }
};
